package gbench.sandbox.plot;

import java.util.*;

import gbench.common.matlib.img.ImageOps;
import gbench.common.matlib.MatlibCanvas;

import static java.lang.Math.*;
import static gbench.common.matlib.img.ImageOps.*;
import static gbench.common.matlib.MatlibCanvas.*;
import static gbench.common.tree.LittleTree.*;
import static gbench.common.tree.LittleTree.IRecord.*;


/**
 * 简单的绘图-饼形图
 * @author gbench
 *
 */
public class JunitPlotPie {
    
    /**
     * 绘制饼形图
     * @param dataframe 数据框 一维数据框{key,value} 结构
     */
    public void plot_pie(final IRecord dataframe) {
        final var size = 1000;
        final var matlib = new MatlibCanvas(size);
        final var sum = dataframe.collect(dbl_stats2(kv2dbl2)).getSum(); // 获取绘图量的累计和，以备后续标准化
        
        matlib.plot(size, size / 2, pen -> {
            final var thetas = new ArrayList<>( dataframe.stream(kv2dbl2)
                .map(e->e/sum*2*PI) //标准化数据，统一到0到1的范围，以方便后序拉伸，即标准化得数据更筋道
                .reduce( new LinkedList<Double>(),      
                    (aa,a)  -> { aa.add((aa.size()<1?0d:aa.getLast())+a);return aa;},
                    (aa,bb) -> { aa.addAll(bb);return aa; }));// 累次规约成列表结构，即把绘图量压制到同一轴向：圆周弧度 轴
            
            thetas.stream().map(kvp_int()).forEach( tup -> { // 沿着弧度方向依次绘制扇形分量
                final var start = tup._1()==0 ? 0 : thetas.get(tup._1()-1);// 起点角度
                final var end = tup._2();// 终点角度
                pen.setColor(ImageOps.rndrgb()).drawPoints( // 设置绘图颜色并 绘制点向量
                    Range.cph( // 构造极坐标系统
                        Range.of(100,200).limit(200), // rho: 向量长度,精度200
                        Range.of(start, end).limit((end-start)*(2000/(2*PI))) // theta: 角度范围,精度 一周 2000分
                    ).map(vec->matlib.rhoTheta(vec.get(0), vec.get(1))).map(e->e.affine_offset(300,210)) // 平移到原点  
                );// drawPoints
            }); // forEach 
            
        },true);// matlib.plot
        
    }
    
    public static void main(String[] args) {
        final var data = REC(
            "一月销售",rndint(1000),
            "二月销售",rndint(1000),
            "三月销售",rndint(1000),
            "四月销售",rndint(1000),
            "五月销售",rndint(1000),
            "六月销售",rndint(1000)
        );// 源数据
        new JunitPlotPie().plot_pie(data);
    }

}
